package log

import (
	"fmt"
	"sync"
	"time"
)

// TODO 异步调用add的情况如何保证同步

const (
	// recorderStartTag 开始标识
	recorderStartTag = "[START]"

	// recorderEndTag 结束标识
	recorderEndTag = "[END]"
)

// logStack 日志堆栈类型
type logStack []string

// Recorder 记录者对象
type Recorder struct {
	sync.RWMutex
	id        string
	stack     logStack
	startTime int64
	endTime   int64
}

// Debug DEBUG日志
func (r *Recorder) Debug(format string, v ...interface{}) {
	r.Lock()
	defer r.Unlock()

	r.add(formatLog(time.Now(), DebugTag, fmt.Sprintf(format, v...), 2))
}

// Info INFO日志
func (r *Recorder) Info(format string, v ...interface{}) {
	r.Lock()
	defer r.Unlock()

	r.add(formatLog(time.Now(), InfoTag, fmt.Sprintf(format, v...), 2))
}

// Warn WARN日志
func (r *Recorder) Warn(format string, v ...interface{}) {
	r.Lock()
	defer r.Unlock()

	r.add(formatLog(time.Now(), WarnTag, fmt.Sprintf(format, v...), 2))
}

// Error ERROR日志
func (r *Recorder) Error(format string, v ...interface{}) {
	r.Lock()
	defer r.Unlock()

	r.add(formatLog(time.Now(), ErrorTag, fmt.Sprintf(format, v...), 2))
}

// Fatal FATAL日志
func (r *Recorder) Fatal(format string, v ...interface{}) {
	r.Lock()
	defer r.Unlock()

	r.add(formatLog(time.Now(), FatalTag, fmt.Sprintf(format, v...), 2))
}

// Write 调用Logger输出日志
func (r *Recorder) Write() {
	r.Lock()
	defer r.Unlock()

	stdLogger.write(r.stack...)
}

// Start 开始记录
func (r *Recorder) Start() {
	r.Lock()
	defer r.Unlock()

	r.startTime = time.Now().Unix()

	msg := fmt.Sprintf("%s %-68s", r.id, "=====================================================================")
	r.add(formatLog(time.Unix(r.startTime, 0), recorderStartTag, msg, 3))
}

// End 结束记录
func (r *Recorder) End() {
	r.Lock()
	defer r.Unlock()

	r.endTime = time.Now().Unix()

	msg := fmt.Sprintf("%s %-68s", r.id, "=====================================================================")
	r.add(formatLog(time.Unix(r.endTime, 0), recorderEndTag, msg, 3))
}

// add 添加记录
func (r *Recorder) add(log string) {
	if nil == r.stack {
		r.stack = make(logStack, 0)
	}

	r.stack = append(r.stack, log)
}
